package com.fanpan26.algo.sort.practice;

/**
 * @author fanpan26
 */
public class Day20191108Sort extends AbstractDaySort {

    public static void main(String[] args) {
        Day20191108Sort sort = new Day20191108Sort();
        sort.run();
    }


    /**
     * 冒泡排序
     * 相邻的挨个比较，并交换
     *
     * @param arr
     */
    @Override
    protected int[] sortByBubble(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
        return arr;
    }

    /**
     * 插入排序
     * 分为已排序部分和未排序部分
     *
     * @param arr
     */
    @Override
    protected int[] sortByInsertion(int[] arr) {

        for (int i = 1; i < arr.length; i++) {
            int value = arr[i];
            int j = i - 1;
            for (; j >= 0; j--) {
                if (arr[j] > value) {
                    arr[j + 1] = arr[j];
                } else {
                    break;
                }
            }
            arr[j + 1] = value;
        }

        return arr;
    }

    /**
     * 选择排序
     * 选择最小的和当前索引交换
     *
     * @param arr
     */
    @Override
    protected int[] sortBySelection(int[] arr) {
        int minIndex;
        for (int i = 0; i < arr.length - 1; i++) {
            minIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[minIndex]) {
                    minIndex = j;
                }
            }
            int temp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }
        return arr;
    }

    /**
     * 桶排序
     *
     * @param arr
     */
    @Override
    protected int[] sortByBucket(int[] arr) {
        return new int[0];
    }

    /**
     * 基数排序
     *
     * @param arr
     */
    @Override
    protected int[] sortByBase(int[] arr) {
        return new int[0];
    }

    /**
     * 计数排序
     *
     * @param arr
     */
    @Override
    protected int[] sortByCounting(int[] arr) {
        return new int[0];
    }

    /**
     * 快速排序
     *
     * @param arr
     */
    @Override
    protected int[] quickSort(int[] arr) {
        quickSort(arr, 0, arr.length - 1);
        return arr;
    }

    private void quickSort(int[] arr, int low, int high) {
        if (low < high) {
            int index = getIndex(arr, low, high);

            quickSort(arr, low, index);
            quickSort(arr, index + 1, high);
        }
    }

    private int getIndex(int[] arr, int low, int high) {
        int value = arr[low];
        while (low < high) {
            while (low < high && value <= arr[high]) {
                high--;
            }
            arr[low] = arr[high];
            while (low < high && value >= arr[low]) {
                low++;
            }
            arr[high] = arr[low];
        }
        arr[low] = value;
        return low;
    }
}
